--施法技能
--                                 施法
--                    ----------------------------
--                    |                          |
-- 技能起手         开始引导   间隔触发         引导结束           技能结束
--   |                |      | | |               |               |
--   -------------------------------------------------------------
--         前摇阶段        引导持续阶段                    后摇阶段
---@class RedRob.SkillBase
---@field New fun():RedRob.SkillBase
local SkillBase = RedRob.CreateClass("SkillBase")
--技能创建
function SkillBase:OnCreate(casterId,skillId)
    self.casterId = casterId
    self.skillId = skillId
    self.skillTypeFlag = 0  --类型标记位
    self.castPoint = 0      --施法时间点
    self.isEnd = false      --技能结束
    self.callbackList = {}
    ---@type BaseContext
    self.context = {}
    --cd
    self.isInCd = false
    self.maxCd = 0
    self.curCd = 0
    --引导
    self.isInChannel = false    --引导中
    self.channelInterval = 0  --引导触发间隔
    self.channelTime = 0      --引导阶段总时长
    self.channelCurTime = 0
    self.channelCount = 0       --引导次数
end
function SkillBase:OnDestroy()
    self.callbackList = {}
end
function SkillBase:Update(dt)
    if self.isEnd then return end
    if self.isInCd then
        self.curCd = self.curCd + dt
        if self.curCd >= self.maxCd then
            self.isInCd = false
            self.curCd = self.maxCd
            self:CoolDownFinished()
        end
    end
    if self.isInChannel then
        self.channelCurTime = self.channelCurTime + dt
        if self.channelCurTime >= self.channelTime then
            self:OnChannelFinish()
        elseif self.channelCurTime >= (self.channelCount + 1) * self.channelInterval then
            self.channelCount = self.channelCount + 1
            self:OnChannelThink()
        end
    end
end
---CD倒计时
function SkillBase:StartCoolDown(time)
    self.maxCd = time
    self.curCd = 0
    self.isInCd = true
end

---引导开始计时
function SkillBase:StartChannel(totalTime,interval)
    self.channelCurTime = 0
    self.channelCount = 0
    self.channelTime = totalTime
    self.isInChannel = true
    self.channelInterval = interval
end
---CD倒计时结束
function SkillBase:CoolDownFinished()

end
function SkillBase:IsInCD()
    return self.isInCd
end
---技能初始化
function SkillBase:OnSkillInit()
    self.isEnd = false
end
---技能起手(前揺)
function SkillBase:OnSkillStart()

end
---技能施法
function SkillBase:OnSkillSpell()

end

---引导开始
function SkillBase:OnChannelStart()

end
---引导间隔触发
function SkillBase:OnChannelThink()

end
---引导结束
function SkillBase:OnChannelFinish()

end

---技能后摇
function SkillBase:OnSkillBackSwing()

end
---技能结束
function SkillBase:OnSkillEnd()
    self.isEnd = true
    self:DoSkillCallback(RedRob.Config.SkillCallbackType.skillEnd,self:CreateBaseContext())
end
---激活类技能 打开
function SkillBase:OnSkillActivate()

end
---激活类技能 关闭
function SkillBase:OnSkillDeactivate()

end
--region callback
function SkillBase:RegisterCallback(callbackType,tb,callback,autoRemove)
    local tbList = self.callbackList[callbackType]
    if not tbList then
        tbList = {}
        self.callbackList[callbackType] = tbList
    end
    for k,v in pairs(tbList) do
        if v.tb == tb and v.callback == callback then
            return
        end
    end
    local temp = TablePool.Get()
    temp.tb = tb
    temp.callback = callback
    temp.autoRemove = autoRemove
    table.insert(tbList,temp)
end
function SkillBase:UnRegisterCallback(callbackType,tb,callback)
    local tbList = self.callbackList[callbackType]
    if not tbList then return end
    for k,v in pairs(tbList) do
        if v.tb == tb and v.callback == callback then
            table.remove(tbList,k)
            TablePool.ReleaseDeeper(v,false)
            return
        end
    end
end
---@private
---@param context BaseContext
function SkillBase:DoSkillCallback(callbackType,context)
    local tbList = self.callbackList[callbackType]
    if not tbList then return end
    local tb = TablePool.Get()
    for k,v in pairs(tbList) do
        table.insert(tb,v)
    end
    for k,v in pairs(tb) do
        v.callback(v.tb,context)
        if v.autoRemove then
            self:UnRegisterCallback(callbackType,v.tb,v.callback)
        end
    end
    TablePool.ReleaseDeeper(tb,false)
end
function SkillBase:CreateBaseContext()
    ---@type BaseContext
    local context = self.context
    context.skillId = self.skillId
    context.casterId = self.casterId
    return context
end
--endregion callback